package cn.hl.hm.service.impl;

import cn.hl.hm.constants.DriverStatus;
import cn.hl.hm.dao.*;
import cn.hl.hm.entity.*;
import cn.hl.hm.service.DriverVehicleService;
import cn.hl.hm.service.OrderService;
import cn.hl.hm.service.PushToAppIService;
import cn.hl.hm.util.List2Map;
import cn.hl.hm.util.OrderUtil;
import com.vizhuo.utils.DateUtil;
import jxl.Sheet;
import jxl.Workbook;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

@Service
public class OrderServiceImpl implements OrderService{
	@Autowired
	private OrderMapper orderMapper;
	@Autowired
	private RouteVehiclePriceMapper routeVehiclePriceMapper;
	@Autowired
	private RouteMapper routeMapper;
	@Autowired
	private CouponMapper couponMapper;
	@Autowired
	private DriverMapper driverMapper;
	@Autowired
	private OrderRulesMapper rulesMapper;
	@Autowired
	private OrderReviewMapper reviewMapper;
	@Autowired
	private VehicleTypeMapper vehicleTypeMapper;
	 @Autowired
	 @Qualifier("pushToAppServiceImpl")
    private PushToAppIService pushToAppIService;
	@Autowired
    private CountrySubdivisionCodeMapper countrySubdivisionCodeMapper;
	@Autowired
    private DriverVehicleService driverVehicleService;

	
	@Override
	public int add(Order order) {
		
		return orderMapper.insertSelective(order);
	}
	
	public RouteVehiclePrice selectPrice(Integer id) {
		
		return routeVehiclePriceMapper.selectByPrimaryKey(id);
	}
	

	public Double selectMills(Integer id){
		RouteVehiclePrice routeVehiclePrice = routeVehiclePriceMapper.selectByPrimaryKey(id);
		if(routeVehiclePrice!=null&&routeVehiclePrice.getRouteId()!=null){
			Route rote = routeMapper.selectByPrimaryKey(routeVehiclePrice.getRouteId());
			if(rote!=null){
				return rote.getRouteMileage();
			}else {
				return null;
			}
		}else {
			return null;
		}
	}
	
	public Coupon selectMostfavorable(Map<String, String> map){
		return couponMapper.selectMostfavorable(map);
		
	}

	@Override
	public List<Driver> selectDriver(Driver driver) {
		return driverMapper.selectDriver(driver);
	}

	@Override
	public List<Order> selectOrder(Order order) {
		return orderMapper.selectOrder(order);
	}

	@Override
	public int updateOrderById(Order order) {
		return orderMapper.updateByPrimaryKeySelective(order);
	}
 
	@Override
	public List<RouteVehiclePrice> selectRouteVehiclePrice(RouteVehiclePrice driver) {
		return routeVehiclePriceMapper.selectRouteVehiclePrice(driver);
	}
	@Override
	public Route selectRoute(Integer id) {
		return routeMapper.selectByPrimaryKey(id);
	}

	@Override
	public int addOrderReview(OrderReview review) {
		return reviewMapper.insertSelective(review);
	}

	@Override
	public List<OrderReview> selectOrderReview(OrderReview review) {
		return reviewMapper.selectReviews(review);
	}

	@Override
	public List<Coupon> selectCoupon(Coupon cp) {
		// TODO Auto-generated method stub
		return couponMapper.selectCoupon(cp);
	}
	
	
	@Override
	public int updateCoupon(Coupon cp) {
		// TODO Auto-generated method stub
		return couponMapper.updateByPrimaryKeySelective(cp);
	}

	@Override
	public Order selectUserSuccess(Order order) {
		// TODO Auto-generated method stub
		return orderMapper.selectUserSuccess(order);
	}

	@Override
	public OrderRules selectOrderRules( ) {
		// TODO Auto-generated method stub
		return rulesMapper.selectOrderRules();
	}

	@Override
	public int addOrderOrderRules(OrderRules rules ) {
		//先查寻有还是没有
		int i = 0;
		OrderRules res = selectOrderRules();
		if(res==null){
			OrderRules or = new OrderRules();
			or.setCreateTime(new Date());
			or.setEffective("1");//有效标识：0无效 1有效
			or.setStandard("1");//1 比例 2固额
			or.setRoleId(rules.getRoleId());
			or.setInfoFeeRatio(rules.getInfoFeeRatio());
			or.setRewardRetio(rules.getRewardRetio());
			i = rulesMapper.insertSelective(rules);
		}else {
			res.setCreateTime(new Date());
			res.setEffective("1");//有效标识：0无效 1有效
			res.setStandard("1");//1 比例 2固额
			res.setRoleId(rules.getRoleId());
			res.setInfoFeeRatio(rules.getInfoFeeRatio());
			res.setRewardRetio(rules.getRewardRetio());
			i = rulesMapper.updateByPrimaryKeySelective(res);
		}
		return i;
	}

	@Override
	public VehicleType selectCarType(Integer id) {
		// TODO Auto-generated method stub
		return vehicleTypeMapper.selectByPrimaryKey(id);
	}

	@Override
	public OrderRules selectOrderRulesById(Integer id) {
		// TODO Auto-generated method stub
		return rulesMapper.selectByPrimaryKey(id);
	}

	@Override
	public List<Order> selectOrderForH5(Order order) {
		// TODO Auto-generated method stub
		return orderMapper.selectOrderForH5(order);
	}

    @Override
    public Map<String, Object> importOrderExcel(MultipartFile file) {
		Map<String, Object> resultMap=new HashMap<>();
		try {
			InputStream is = file.getInputStream();
			Workbook rwb = Workbook.getWorkbook(is);
			Sheet rs=rwb.getSheet(0);
			int clos=rs.getColumns();
			int rows=rs.getRows();
			resultMap.put("totleRows",rows-1);
			List<Map<String, String>> failData=new ArrayList<Map<String, String>>();
			//成功导入条数
			int succeeedRows=0;
			if (rs.getRows()>1) {
				//托运日期
				String consignDate=null;
				//时间
				String consignTime=null;
				//收货日期
				String receiptDate=null;
				//货币总金额
				String totalAmount=null;
				//发货地
				String sendPlace=null;
				//收货地
				String receivingPlace=null;
				//手机号
				String phoneNumber=null;
				//车牌号
				String plateNumber=null;

				Map<String,String> rowData=new HashMap<>();
				String errorMessage=null;
				Driver driver=new Driver();
				List<Driver> drivers = driverMapper.selectDriver(driver);
				Map<String,Driver> driverMap= List2Map.getInstance().tobeMap("getDriverAccount",drivers);
				Map<String,List<CountrySubdivisionCode>> countrySubdivisionCodeMap = List2Map.getInstance().tobeLinkedHashMaps("getCscName",countrySubdivisionCodeMapper.selectAll());
				Map<String,List<DriverVehicle>> driverVehicleMap = List2Map.getInstance().tobeLinkedHashMaps("getPlateNumber",driverVehicleService.selectByDIVI(null, null));
				Map<String,List<Order>> orderMap=List2Map.getInstance().tobeMaps("getPlateNumber",selectOrder(new Order()));
				List<DriverVehicle> driverVehicles=null;
				//从第二行开始读
				for (int x = 1; x <=rows-1; x++) {
					//当时最后一行的时候下标减一防止越界
					consignDate=rs.getCell(0, x).getContents();
					consignTime=rs.getCell(1, x).getContents();
					receiptDate=rs.getCell(2, x).getContents();
					totalAmount=rs.getCell(3, x).getContents();
					sendPlace=rs.getCell(4, x).getContents();
					receivingPlace=rs.getCell(5, x).getContents();
					phoneNumber=rs.getCell(6, x).getContents();
					plateNumber=rs.getCell(7, x).getContents();

					errorMessage=checkData(consignDate, consignTime, receiptDate, totalAmount, sendPlace, receivingPlace, phoneNumber,plateNumber,
							driverMap,countrySubdivisionCodeMap,driverVehicleMap.get(plateNumber),orderMap);
					if (errorMessage==null) {
						Order order = new Order();
						order.setOrderCode(OrderUtil.getInstance().getOrderCode());
						order.setOrderStatus("7");
						order.setPayType("6");
						order.setDriverPhone(phoneNumber);
						order.setGoodsName("百货");
						//校验sendPlace receivingPlace  countrysubdivisioncode route
						order.setLineName(sendPlace+"-"+receivingPlace);
						//					是否是金额
						order.setTotalPrice(new BigDecimal(totalAmount));
						order.setPayPrice(order.getTotalPrice());
						//校验时间格式
						order.setCreateTime(DateUtil.string2Date(consignDate+" "+consignTime));

						Date acceptDT=DateUtil.string2Date(receiptDate+" "+consignTime);
						//到货时间 需减40分钟，需小于当前时间
						order.setAcceptTime(new Date(acceptDT.getTime()-40*60*1000));
						//用车时间
						order.setUseTime(order.getCreateTime());
						//支付时间 收货日期减20分钟
						order.setPayTime(new Date(acceptDT.getTime()-20*60*1000));
						//用户确认到货时间 收货日期减12分钟
						order.setUserEnsureTime(new Date(acceptDT.getTime()-12*60*1000));
						//起始地址
						order.setSrcAddress(sendPlace);
						//目的地
						order.setDestAddress(receivingPlace);
						order.setEffective("0");
						order.setLoginkStatus(0);
						order.setOrderSource(1);
						order.setPlateNumber(driverVehicleMap.get(plateNumber).get(0).getPlateNumber());
						int n=0;
						try {
							n=add(order);
						} catch (Exception e) {
							e.printStackTrace();
						}
						if (n>0){
							succeeedRows+=1;
						}else{
							fillErrorData(consignDate, consignTime, receiptDate, totalAmount, sendPlace,
									receivingPlace, phoneNumber, plateNumber,errorMessage, failData,rowData);
						}
					}else{
						fillErrorData(consignDate, consignTime, receiptDate, totalAmount, sendPlace,
								receivingPlace, phoneNumber, plateNumber,errorMessage, failData, rowData);
					}
				}
				//更新司机和线路关联数据
				if (succeeedRows>0) {
					try {
						orderMapper.importOrder();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
			resultMap.put("succeeedRows",succeeedRows);
			resultMap.put("failRows",failData.size());
			resultMap.put("nonExecutionRows",(rows-1-succeeedRows-failData.size())<0?0:(rows-1-succeeedRows-failData.size()));
			resultMap.put("failRowList",failData);
			return resultMap;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
    }

	@Override
	public List<Order> selectByPrimaryKeySelective(Order record) {
		return orderMapper.selectByPrimaryKeySelective(record);
	}

	private void fillErrorData(String consignDate, String consignTime, String receiptDate, String totalAmount,
							   String sendPlace, String receivingPlace, String phoneNumber, String plateNumber,String errorMessage,
							   List<Map<String, String>> failData,Map<String, String> rowData) {
		rowData=new HashMap<>();
		rowData.put("consignDate",consignDate);
		rowData.put("consignTime",consignTime);
		rowData.put("receiptDate",receiptDate);
		rowData.put("totalAmount",totalAmount);
		rowData.put("sendPlace",sendPlace);
		rowData.put("receivingPlace",receivingPlace);
		rowData.put("phoneNumber",phoneNumber);
		rowData.put("plateNumber",plateNumber);
		rowData.put("errorMessage",errorMessage);
		failData.add(rowData);
	}

	private String checkData(String consignDate, String consignTime, String receiptDate, String totalAmount,
							 String sendPlace, String receivingPlace, String driverPhone, String plateNumber,
							 Map<String, Driver> driverMap, Map<String, List<CountrySubdivisionCode>> countrySubdivisionCodeMap,
							 List<DriverVehicle> driverVehicles,Map<String,List<Order>> orderMap) {
		try {
			if (StringUtils.isBlank(driverPhone)) {
                return "手机号为空";
            }else if(driverMap.get(driverPhone)==null){
                return "手机号匹配不到司机";
            }else if(!DriverStatus.PASS.getStatus().equals(driverMap.get(driverPhone).getDriverStatus())){
                return "手机号对应司机非正常状态";
            }
			if(StringUtils.isBlank(sendPlace) || !countrySubdivisionCodeMap.containsKey(sendPlace)){
                return "未匹配到发货地";
            }
			if(StringUtils.isBlank(receivingPlace) || !countrySubdivisionCodeMap.containsKey(receivingPlace)){
                return "未匹配到收货地";
            }
			try {
                if (StringUtils.isBlank(totalAmount) ||new BigDecimal(totalAmount)==null) {
                    return "货币总金额错误";
                }
            } catch (Exception e) {
                return "货币总金额错误";
            }

			if (StringUtils.isBlank(consignDate) || DateUtil.string2DateNoTime(consignDate)==null) {
                return "托运日期错误";
            }

			if (StringUtils.isBlank(receiptDate) ||DateUtil.string2DateNoTime(receiptDate)==null) {
                return "收货日期错误";
            }

			if (StringUtils.isBlank(consignTime) ||DateUtil.string2Time(consignTime)==null) {
                return "时间错误";
            }
			if (DateUtil.string2Date(receiptDate+" "+consignTime).compareTo(new Date())>0) {
                return "托运日期超过当前时间";
            }
			if (StringUtils.isBlank(plateNumber)) {
				return "车牌号为空";
			}
			if (driverVehicles==null || driverVehicles.size()==0) {
				return "车牌号和手机号不匹配";
			}else{
				for (int i = 0; i < driverVehicles.size(); i++) {
					if (driverVehicles.get(i).getDriverId().equals(driverMap.get(driverPhone).getId())) {
						driverVehicles.set(0,driverVehicles.get(i));
						break;
					}
					if(i==driverVehicles.size()-1 &&
							!driverVehicles.get(i).getDriverId().equals(driverMap.get(driverPhone).getId())){
						return "车牌号和手机号不匹配";
					}
				}
			}
			Date createTime=DateUtil.string2Date(consignDate+" "+consignTime);
			Date useTime=DateUtil.string2Date(consignDate+" "+consignTime);
			Date userEnsureTime=new Date(DateUtil.string2Date(receiptDate+" "+consignTime).getTime()-12*60*1000);

			//因为性能问题未处理并发提交问题，数据库里可能会出现重复
			//判断运单是否重复  防止数据库已存在重复

			List<Order> orders=orderMap.get(plateNumber);
			if (List2Map.getInstance().isNotEmpty(orders)) {
				for (Order order: orderMap.get(plateNumber)) {
					if(order.getCreateTime().equals(createTime)
							&& order.getUseTime().equals(useTime)
							&& order.getUserEnsureTime().equals
							(userEnsureTime)){
						return "司机已导入相同时间运单";
					}
				}
				//防止本地提交有重复
				Order order=new Order();
				order.setCreateTime(createTime);
				order.setUseTime(useTime);
				order.setUserEnsureTime(userEnsureTime);
				orders.add(order);
				orderMap.put(plateNumber,orders);
			}else{
				orders=new ArrayList<>();
				//防止本地提交有重复
				Order order=new Order();
				order.setCreateTime(createTime);
				order.setUseTime(useTime);
				order.setUserEnsureTime(userEnsureTime);
				orders.add(order);
				orderMap.put(plateNumber,orders);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return "数据校验异常";
		}
		return null;
	}


}
